package org.oep.jmingle;

import java.util.Random;

import javax.microedition.lcdui.Image;

public class Utils {
	
	private static final String consonants = "bcdfghjklmnpqrstvwxyz";
	private static final String vowels = "aeiou";
	private static final String hardConsonants = "cdgkpqt";
	private static final String softConsonants = "flnrs";
	
	public static String preciseTimeDiff(long diff) {
		int ms = (int) diff % 1000;
		int s = (int) diff / 1000;
		return s + "." + ms + "s";
	}
	
	public static String friendlyTimeDiff(long diff) {
		int ms = (int) diff % 1000;
		int seconds = (int) diff / 1000;
		int minutes = seconds / 60;
		int hours = minutes / 60;
		int days = hours / 24;
		int weeks = days / 7;
		
		String out = new String();

		if(weeks > 0){
			out += weeks + "w";
		} else if(days > 0) {
			out += days + "d";
		} else if(hours > 0) {
			out += hours + "h";
		} else if(minutes > 0) {
			out += minutes + "m";
		} else if(seconds > 0){
			out += seconds + "s";
		} else {
			out += ms + "ms";
		}
		return out;
	}
	
	public static String friendlyTimeDiffNow(long time) {
		if(time < 0) return "Never";
		System.out.println("Now(" + System.currentTimeMillis() + ") - " + time);
		return friendlyTimeDiff(System.currentTimeMillis() - time);
	}
	
	public static long hexToDecimal(String number) {
		long dec = 0;
		for(int i = 0; i < number.length(); i++) {
			char c = number.charAt(i);
			long trueval = hexDigitEquivalent(c) * pow(16, number.length() - i - 1);
			dec += trueval;
		}
		return dec;
	}
	
	public static int hexDigitEquivalent(char c) {
		c = java.lang.Character.toUpperCase(c);
		switch(c) {
		case '1': return 1;
		case '2': return 2;
		case '3': return 3;
		case '4': return 4;
		case '5': return 5;
		case '6': return 6;
		case '7': return 7;
		case '8': return 8;
		case '9': return 9;
		case 'A': return 10;
		case 'B': return 11;
		case 'C': return 12;
		case 'D': return 13;
		case 'E': return 14;
		case 'F': return 15;
		default: return 0;
		}
	}
	
	public static long pow(long b, long e) {
		long n = 1;
		for(int i = 0; i < e; i++)
			n = n * b;
		return n;
	}
	
	public static String makeName(long seed) {
		Random r = new Random(seed);
		
		int size = r.nextInt(5) + 3;
		
		String name = new String();
		while(name.length() < size) {
			if(r.nextInt(2) == 0) { // Do a vowel
				if(name.length() == 0) {
					// Add a vowel by default
					name += vowels.charAt( r.nextInt( vowels.length() ) );
				}
				else if(vowels.indexOf( name.charAt(name.length() - 1) ) < 0) {
					// Add a vowel if the previous isn't a vowel
					name += vowels.charAt( r.nextInt( vowels.length() ) );
				} else {
					// Add a consonant instead
					name += consonants.charAt( r.nextInt( consonants.length() ) );
				}
			} else {
				if(name.length() == 0) {
					// Add a consonant by default
					name += consonants.charAt( r.nextInt( consonants.length() ) );
				}
				else if(vowels.indexOf( name.charAt(name.length() - 1) ) >= 0) {
					// Add any consonant if the previous is a vowel or softConsonant
					name += consonants.charAt( r.nextInt( consonants.length() ) );
				} else if (name.length() > 1 && softConsonants.indexOf( name.charAt(name.length() - 1) ) >= 0) {
					// Add a hard consonant if the previous was a soft one
					// Don't do it if that soft consonant is the first letter
					name += hardConsonants.charAt( r.nextInt( hardConsonants.length() ) );
				}
				else {
					// Add a vowel instead
					name += vowels.charAt( r.nextInt( vowels.length() ) );
				}	
			}
				
		}
		return name.substring(0,1).toUpperCase() + name.substring(1);
	}
	
	public static Image customizeMinglet(Image source, String hash) {
		if(source == null) return null;
		
		Random r = new Random( hexToDecimal(hash) );
		int base = r.nextInt( 0xFFFFFF + 1 );
		int accent = r.nextInt( 0xFFFFFF + 1 );
		
		source = changeColor(source, 0x0000FF, base);
		source = changeColor(source, 0xFF0000, accent);
		return source;
	}
	
	public static Image changeColor(Image source, int fromColor, int toColor) {
		int imageWidth = source.getWidth();
		int imageHeight = source.getHeight();
		
		int[] rgb = new int[imageWidth * imageHeight];
		
		int deviceColor = getDeviceColor(fromColor);
		toColor = getDeviceColor(toColor);
		
		source.getRGB(rgb, 0, imageWidth, 0, 0, imageWidth, imageHeight);
 
		int count = 0;
		for(int i = 0; i < rgb.length; i++)
		{
			if(rgb[i] == deviceColor)
			{
				rgb[i] = toColor;
				count++;
			}
		}
		return Image.createRGBImage(rgb, imageWidth, imageHeight, true);
	}
	
	public static Image blend(Image source, int alpha) {
		if(alpha > 0xFF || alpha < 0x00) return source;
		alpha = alpha << 24;
		
		int width = source.getWidth();
		int height = source.getHeight();
		
		int [] raw = new int [ width * height ];
		source.getRGB(raw, 0, width, 0, 0, width, height);
		
		for(int i = 0; i < raw.length; i++) {
			// Extract just the color
			//System.out.println("Before: " + Integer.toHexString(raw[i]));
			int color = (raw[i] & 0x00FFFFFF);
			//System.out.println("After: " + Integer.toHexString(color));
			
			// Add in the new alpha
			color += alpha;
			raw[i] = color;
		}
		
		return Image.createRGBImage(raw, width, height, true);
	}
	
	public static boolean isWhite(Image source) {
		int width = source.getWidth();
		int height = source.getHeight();
		
		int [] raw = new int [ width * height ];
		source.getRGB(raw, 0, width, 0, 0, width, height);
		
		for(int i = 0; i < raw.length; i++) {
			int color = (raw[i] & 0x00FFFFFF);
			if(color != 0xFFFFFF) return false;
		}
		return true;
	}
	
	public static int getDeviceColor(int color) {
		Image fake = Image.createRGBImage(new int[]{color}, 1, 1, false);
		
		int[] rgb = new int[1];
		
		fake.getRGB(rgb, 0, 1, 0, 0, 1, 1);
		
		return rgb[0];
	}

	public static Actor makeActor(String hash, String owner) {
		return makeActor(hash, owner, -1);
	}
	
	public static Actor makeActor(String hash, String owner, long time) {
		System.out.println("MakeActor got " + time);
		Actor a = new Actor(hash, owner, time);
		a.addAnimation(Actor.WALK_RIGHT, "/res/animations/minglet/jump-right.png", 34, 34);
		a.addAnimation(Actor.WALK_UP, "/res/animations/minglet/jump-up.png", 34, 34);
		a.addAnimation(Actor.WALK_DOWN, "/res/animations/minglet/jump-down.png", 34, 34);
		a.addAnimation(Actor.STAND_STILL, "/res/animations/minglet/standing.png", 28, 29);
		return a;
	}
}
